package cn.tedu.submarine;

import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
/**
 * 整个游戏世界
 */
public class World extends JPanel{
    int x;
    public static final int WIDTH =641;//窗口的宽       常量
    public static final int HEIGHT =479;//窗口的高

    public static final int RUNNING =1;//游戏运行
    public static final int GAME_OVER =0;//游戏结束
    private int state = RUNNING;//默认运行


    private Battleship ship =new Battleship();//战舰
    private SeaObject[] submarine ={};
    private Mine[] mines = {};
    private Bomb[] bombs = {};

    //重写paint(),画对象
    public void paint(Graphics g){
        switch (state){
            case GAME_OVER:
                Images.gameover.paintIcon(null,g,0,0);
                break;
            case RUNNING:
                Images.sea.paintIcon(null,g,0,0);
                ship.paintImage(g);
                for (int i = 0; i <submarine.length ; i++) {
                    submarine[i].paintImage(g);
                }
                for (int i = 0; i <mines.length ; i++) {
                    mines[i].paintImage(g);
                }
                for (int i = 0; i <bombs.length ; i++) {
                    bombs[i].paintImage(g);
                }
                g.drawString("SCORE:"+score,200,50);
                g.drawString("LIFE:"+ship.getLife(),100,50);
        }
    }

    //生成鱼雷水雷,侦查潜艇,控制几率生成
    public SeaObject nextSubmarine(){
        Random rd = new Random();
        int type = rd.nextInt(20);//0~19随机数
        if(type<10){
            return new ObserveSubmarine();//返回侦查潜艇
        }else if(type<15){
            return new TorpedoSubmarine();//返回水雷潜艇
        }else{
            return new MineSubmarine();//返回鱼雷潜艇
        }
    }

    //水雷入场
    private int mineEnterAction = 0;
    public void mineEnterAction(){
        mineEnterAction++;//每10毫秒走一次
        if (mineEnterAction%100==0){//每1000毫秒(100*10)走一次
            for (int i = 0; i <submarine.length ; i++) {
                if (submarine[i] instanceof MineSubmarine){
                    MineSubmarine me = (MineSubmarine) submarine[i];

                    Mine obj = me.shotMine();
                    mines = Arrays.copyOf(mines,mines.length+1);
                    mines[mines.length-1]= obj;

                }
            }
        }
    }

    //鱼雷水雷,侦查潜艇入场
    private int subEnterIndex = 0;
    public  void submarineEnterAction(){//鱼雷水雷,侦查潜艇入场,------10毫秒走一次
        subEnterIndex++;//每10毫秒增1
        if(subEnterIndex%40==0){//每400(40*10)毫秒走一次
            SeaObject obj = nextSubmarine();//获取潜艇对象
            submarine = Arrays.copyOf(submarine,submarine.length+1);//扩容,
            submarine[submarine.length-1] = obj;//将obj添加到最后一个元素
        }
    }

    //海洋对象移动
    private int moveAction=0;
    public void moveAction(){
        for (int i = 0; i <submarine.length ; i++) {
            submarine[i].move();
        }
        for (int i = 0; i <mines.length ; i++) {
            mines[i].move();
        }
        for (int i = 0; i <bombs.length ; i++) {
            bombs[i].move();
        }

    }

    /**深水炸弹与潜艇的碰撞*///使用嵌套循环对比
    private int score = 0;
    //判断是获得生命还是分数
    public void bombBangAction(){//每10毫秒走一次
        for (int i = 0; i <bombs.length ; i++) {
            Bomb b = bombs[i];
            for (int j = 0; j <submarine.length ; j++) {
                SeaObject s = submarine[j];//获取每个潜艇
                if (b.isLive() && s.isLive() && s.isHit(b)){//若都活着,并且打击到
                    b.goDead();
                    s.goDead();

                    if (s instanceof EnemyScore){//若被撞为得分
                        EnemyScore es = (EnemyScore) s;//将别撞潜艇强转为分数接口
                        score +=es.getScore();//战舰获分
                    }
                    if (s instanceof EnemyLife){//若被撞潜艇为得命
                        EnemyLife el = (EnemyLife) s;//将被撞潜艇强转为得命接口
                        int num =el.getLife();//获取命数
                        ship.addLife(num);//战舰获得命
                    }

                }
            }
        }
    }
    /**删除越界对象*/
    public void outofBoundsAction(){//每10毫秒走一次
        //遍历所有潜艇,缩容,
        for (int i = 0; i <submarine.length ; i++) {
            if (submarine[i].isOutdfBounds() || submarine[i].isDead()){//判断是否越界
                submarine[i]  =submarine[submarine.length-1];//替换成最后一个元素,使得被删除的元素没有地址,最后一个有两个地址,再缩容,
                submarine = Arrays.copyOf(submarine,submarine.length-1);//缩容
            }
        }
        //遍历所有水雷
        for (int i = 0; i <mines.length ; i++) {
            if (mines[i].isOutdfBounds() || mines[i].isDead()){//判断是否越界
                mines[i]=mines[mines.length-1];//替换成最后一个元素,使得被删除的元素没有地址,最后一个有两个地址,再缩容,
                mines=Arrays.copyOf(mines,mines.length-1);//缩容
            }
        }
        //遍历深水炸弹
        for (int i = 0; i <bombs.length ; i++) {
            if (bombs[i].isOutdfBounds() || bombs[i].isDead()){//判断是否越界
                bombs[i]=bombs[bombs.length-1];//替换成最后一个元素,使得被删除的元素没有地址,最后一个有两个地址,再缩容,
                bombs=Arrays.copyOf(bombs,bombs.length-1);//缩容
            }
        }
    }

    /**战舰与水雷碰撞*/
    public void mineBangAction(){//每10毫秒一次
        for (int i = 0; i <mines.length ; i++) {
            Mine m = mines[i];//获取每个水雷
            if (m.isLive() && ship.isLive() && m.isHit(ship)){
                m.goDead();
                ship.subtractLife();
            }
        }
    }

    /**战舰死亡删除,弹出游戏结束*/
    public void checkGameOverAction(){
        if (ship.getLife()<=0){//战舰没有命数时,
            state = GAME_OVER;//将窗口设置为GAME_OVER游戏结束状态
        }
    }
    //启动程序运行
    public  void action(){

        KeyAdapter k = new KeyAdapter() {
            /**重写keyReleased()按键抬起事件*/
            public void keyPressed(KeyEvent e) {//当按键按下会自动执行(抬起的是keyReleased)
                if (e.getKeyCode()==KeyEvent.VK_X){//若按键是x
                    Bomb obj = ship.shotBmob();//获取深水炸弹对象
                    bombs =Arrays.copyOf(bombs,bombs.length+1);//扩容
                    bombs[bombs.length-1]=obj;//obj添加到最后元素上
                }
                if (e.getKeyCode()==KeyEvent.VK_LEFT){
                    ship.moveLeft();
                }
                if (e.getKeyCode()==KeyEvent.VK_RIGHT){
                    ship.moveRight();
                }
                if (e.getKeyCode()==KeyEvent.VK_DOWN){
                    ship.moveDown();
                }
                if (e.getKeyCode()==KeyEvent.VK_UP){
                    ship.moveup();
                }
            }
        };
        this.addKeyListener(k);//添加侦听

        Timer timer = new Timer();//定时对象
        int interval = 10;//定时间隔
        timer.schedule(new TimerTask() {
            public void run() {//定时干的事(每10毫秒自动执行)
                submarineEnterAction();//潜艇入场
                mineEnterAction();//水雷入场
                moveAction();//海洋移动对象
                outofBoundsAction();//删除越界对象
                bombBangAction();//深水炸弹与潜艇碰撞
                mineBangAction();//战舰减命
                checkGameOverAction();//战舰死亡删除,弹出游戏结束
                repaint();//重复画,(重新调用paint方法)
            }
        }, interval, interval);//定时计划表
    }

    public static void main(String[] args)  {
        JFrame jFrame = new JFrame();//画框
        World world = new World();//画板
        world.setFocusable(true);//获得焦点
        jFrame.add(world);//画框添加画板
        jFrame.setSize(WIDTH,HEIGHT);//设置大小
        jFrame.setLocationRelativeTo(null);//居中
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭程序
        jFrame.setVisible(true);//设置是否可见

        //启动程序执行
        world.action();

    }
}
